package contest.dao;

import contest.util.ErrorLog;
import contest.util.IDataSource;
import contest.util.SqlBundle;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.CallableStatement;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ResourceBundle;

public abstract class ObjectDA {

    protected IDataSource dataSource;
    protected StatementFormat stmtFormat;
    protected SqlBundle bundle;

    public ObjectDA(IDataSource setting, SqlBundle bundle) {
        this.dataSource = setting;
        this.stmtFormat = new StatementFormat();
        this.bundle = bundle;
    }

    private ObjectDA(){}

    protected Connection createConnection() throws SQLException, ClassNotFoundException, InstantiationException, IllegalAccessException {
        Connection conn = null;
        String userName = this.dataSource.getUsername();
        String password = this.dataSource.getPassword();
        String url = this.dataSource.getUrl();
        Class.forName(this.dataSource.getDriver()).newInstance();
        conn = (Connection) DriverManager.getConnection(url, userName, password);
        return conn;
    }

    protected PreparedStatement createPrepareStatement(String propertyName, Connection conn) throws SQLException {
        String sqlStmt = this.getSqlBundle().getString(propertyName);
        return conn.prepareStatement(sqlStmt);
    }

    protected CallableStatement createCallableStatement(String propertyName, Connection conn) throws SQLException {
        String sqlStmt = this.getSqlBundle().getString(propertyName);
        return conn.prepareCall(sqlStmt);
    }

    protected ResourceBundle getSqlBundle() {
        return this.bundle.getResoureBundle(this.getSqlBundleName());
    }

    protected abstract String getSqlBundleName();

    // <editor-fold defaultstate="collapsed" desc="CLOSE CONNECTION. Click on the + sign on the left to edit the code.">
    public void close(Connection c) {
        try {
            if (c != null && !c.isClosed()) {
                c.close();
            }
        } catch (SQLException ex) {
            ErrorLog.catchException(ex);
        }
    }

    public void close(PreparedStatement p) {
        try {
            if (p != null && !p.isClosed()) {
                p.close();
            }
        } catch (SQLException ex) {
            ErrorLog.catchException(ex);
        }

    }

    public void close(ResultSet r) {
        try {
            if (r != null && !r.isClosed()) {
                r.close();
            }
        } catch (SQLException ex) {
            ErrorLog.catchException(ex);
        }

    }

    public void close(CallableStatement o) {
        try {
            if (o != null && !o.isClosed()) {
                o.close();
            }
        } catch (SQLException ex) {
            ErrorLog.catchException(ex);
        }

    }

    protected void close(Connection c, PreparedStatement p, ResultSet r) {
        this.close(c);
        this.close(p);
        this.close(r);
    }

    protected void close(Connection c, PreparedStatement p) {
        this.close(c);
        this.close(p);
    }

    protected void close(Connection c, CallableStatement p) {
        this.close(c);
        this.close(p);
    }

    protected void close(Connection c, CallableStatement p, ResultSet r) {
        this.close(c);
        this.close(p);
        this.close(r);
    }
    // </editor-fold>
}

